c3b12d0f8d57a6a7626bef89633ae968144c8ef1,src/frontend/org/voltdb/planner/PlanAssembler.java,PlanAssembler,getNextUpdatePlan,#,1335

Before Change


        }
        else {
            // Send the local result counts to the coordinator.
            AbstractPlanNode recvNode = SubPlanAssembler.addSendReceivePair(updateNode);
            // add a sum or a limit and send on top of the union
            planRoot = addSumOrLimitAndSendToDMLNode(recvNode, targetTable.getIsreplicated());
        }

        CompiledPlan retval = new CompiledPlan();

After Change


            return getNextUpdatePlan();
        }

        UpdatePlanNode updateNode = new UpdatePlanNode();
        //FIXME: does this assert need to be relaxed in the face of non-from-clause subquery support?
        // It was not in Mike A's original branch.
        assert (m_parsedUpdate.m_tableList.size() == 1);
        Table targetTable = m_parsedUpdate.m_tableList.get(0);
        updateNode.setTargetTableName(targetTable.getTypeName());
        // set this to false until proven otherwise
        updateNode.setUpdateIndexes(false);

        TupleAddressExpression tae = new TupleAddressExpression();
        NodeSchema proj_schema = new NodeSchema();
        // This planner-generated column is magic.
        proj_schema.addColumn(
                AbstractParsedStmt.TEMP_TABLE_NAME,
                AbstractParsedStmt.TEMP_TABLE_NAME,
                "tuple_address", "tuple_address",
                tae);

        // get the set of columns affected by indexes
        Set<String> affectedColumns = getIndexedColumnSetForTable(targetTable);

        // add the output columns we need to the projection
        //
        // Right now, the EE is going to use the original column names
        // and compare these to the persistent table column names in the
        // update executor in order to figure out which table columns get
        // updated.  We'll associate the actual values with VOLT_TEMP_TABLE
        // to avoid any false schema/column matches with the actual table.
        for (Entry<Column, AbstractExpression> colEntry :
            m_parsedUpdate.columns.entrySet()) {
            Column col = colEntry.getKey();
            String colName = col.getTypeName();
            AbstractExpression expr = colEntry.getValue();
            expr.setInBytes(colEntry.getKey().getInbytes());

            proj_schema.addColumn(
                    AbstractParsedStmt.TEMP_TABLE_NAME,
                    AbstractParsedStmt.TEMP_TABLE_NAME,
                    colName, colName,
                    expr);

            // check if this column is an indexed column
            if (affectedColumns.contains(colName)) {
                updateNode.setUpdateIndexes(true);
            }
        }
        ProjectionPlanNode projectionNode =
                new ProjectionPlanNode(proj_schema);


        // add the projection inline (TODO: this will break if more than one
        // layer is below this)
        //
        // When we inline this projection into the scan, we're going
        // to overwrite any original projection that we might have inlined
        // in order to simply cull the columns from the persistent table.
        assert(subSelectRoot instanceof AbstractScanPlanNode);
        subSelectRoot.addInlinePlanNode(projectionNode);

        // connect the nodes to build the graph
        updateNode.addAndLinkChild(subSelectRoot);

        CompiledPlan retval = new CompiledPlan();
        retval.setReadOnly (false);

        if (targetTable.getIsreplicated()) {
            retval.replicatedTableDML = true;
        }

        //FIXME: This assumption was only safe when we didn't support updates
        // w/ possibly non-deterministic subqueries.
        // Is there some way to integrate a "subquery determinism" check here?
        // because we didn't support updates with limits, either.
        // Since the update cannot be inherently non-deterministic, there is
        // no message, and the last parameter is null.
        retval.statementGuaranteesDeterminism(false, true, null);

        if (m_partitioning.wasSpecifiedAsSingle() || m_partitioning.isInferredSingle()) {
            retval.rootPlanGraph = updateNode;
            return retval;
        }

        // Send the local result counts to the coordinator.
        // Add a compensating sum of modified tuple counts or a limit 1
        // AND a send on top of the union-like receive node.
        boolean isReplicated = targetTable.getIsreplicated();
        retval.rootPlanGraph = addCoordinatorToDMLNode(updateNode, isReplicated);
        return retval;
    }